﻿#include "OiPCH.hpp"

namespace Oi
{
    namespace PLScannerCore
    {
        ListItemLabel::ListItemLabel(QWidget* parent/* = NULL*/) : QLabel(parent)
        {
            setWordWrap(true);
            auto f = font();
            f.setPointSize(14);
            setFont(f);
            setStyleSheet("background:rgba(165, 165, 165, 100)");
            setAlignment(Qt::AlignCenter);
            setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
        }

        void ListItemLabel::setDispText(const QString& t)
        {
            _text = t;
            setText(t);
        }

        void ListItemLabel::setSelectText(const QString& st)
        {
            int matchS, matchL;

            if(containsText(st, &matchS, &matchL))
            {
                auto len = _text.length();
                setText(QString("%1<span style=\"background:#ffff00;\"><b>%2</b></span>%3").arg(_text.left(matchS)).arg(_text.mid(matchS, matchL)).arg(_text.right(len - matchS - matchL)));
            }
            else
            {
                setText(_text);
            }
        }

        bool ListItemLabel::containsText(const QString& t, int* start, int* lenth)
        {

            QList<int> ss;
            QList<int> ls;
            QList<int> ts;
            QChar btc;
            int bti = -1;

            for(int ti = 0; ti < t.size(); bti++)
            {
                if(t[ti] != '_' && t[ti] != '-' && t[ti] != ',' && t[ti] != ' ')
                {
                    bti = ti;
                    btc = t[ti];
                    break;
                }
            }

            if(bti < 0)
            {
                if(start) *start = 0;
                if(lenth) *lenth = 0;
                return true;
            }

            for(int si = 0; si < _text.size(); si++)
            {
                if(_text[si] == '_' || _text[si] == '-' || _text[si] == ',' || _text[si] == ' ')
                {
                    for(int & lsi : ls)
                    {
                        lsi++;
                    }
                    continue;
                }

                for(int tsi = 0; tsi < ts.size(); tsi++)
                {
                    int& ti = ts[tsi];

                    do
                    {
                        ti++;
                    } while(ti < t.size() && ( t[ti] == '_' || t[ti] == '-' || t[ti] == ',' || t[ti] == ' ' ));

                    if(ti < t.size())
                    {
                        if(_text[si] == t[ti])
                        {
                            ls[tsi]++;
                        }
                        else
                        {
                            ss.removeAt(tsi);
                            ls.removeAt(tsi);
                            ts.removeAt(tsi);

                            tsi--;

                            continue;
                        }
                    }

                    if(ti >= t.size() - 1)
                    {
                        if(start) *start = ss[tsi];
                        if(lenth) *lenth = ls[tsi];
                        return true;
                    }
                }

                if(_text[si] == btc)
                {
                    ss.push_back(si);
                    ls.push_back(1);
                    ts.push_back(0);
                }
            }

            return false;
        }

        class ProductDlgImpl : public Impl<ProductDlg>
        {
        public:
            void init(ProductMeasurePage type);

            void update();

            void addItem(QString name);

            void setCurrent(QString name);

        public:
            QLineEdit* _searchName;
            QPushButton* _clearSearch;

            QListWidget* _formulaList;

            QPushButton* _appendButton;
            QPushButton* _modifyButton;
            QPushButton* _deleteButton;

            QPushButton* _completeButton;
            QPushButton* _cancelButton;

            ProductWidget* _productViewer;

        public:
            QMap<QString, QListWidgetItem*> _items;
            QString _currentProduct;
            int _operator;
        };

        void ProductDlgImpl::init(ProductMeasurePage type)
        {
            OI_Q(ProductDlg);

            q->setWindowTitle(ProductDlg::tr("规格管理器"));

            auto font = q->font();
            font.setPixelSize(18);

            QHBoxLayout* formulaLayout = new QHBoxLayout(q);
            formulaLayout->setContentsMargins(2, 0, 2, 0);
            formulaLayout->setSpacing(2);
            
            auto listWidget = new QWidget();
            listWidget->setMinimumWidth(200);
            QVBoxLayout* formulaListLayout = new QVBoxLayout(listWidget);
            formulaListLayout->setContentsMargins(0, 0, 0, 0);
            formulaListLayout->setSpacing(2);
 
            QHBoxLayout* searchNameLayout = new QHBoxLayout();
            searchNameLayout->setContentsMargins(0, 0, 0, 0);
            searchNameLayout->setSpacing(2);
            _searchName = new QLineEdit();
            _searchName->setObjectName("_searchName");
            _searchName->setPlaceholderText(ProductDlg::tr("产品搜索关键字"));
            _searchName->setFont(font);

            _clearSearch = new QPushButton(ProductDlg::tr("清空"));
            _clearSearch->setObjectName("_clearSearch");
            _clearSearch->setFont(font);
            searchNameLayout->addWidget(_searchName, 1);
            searchNameLayout->addWidget(_clearSearch);

            _formulaList = new QListWidget();
            _formulaList->setObjectName("_formulaList");
            _formulaList->setGridSize(QSize(260, 55));
            _formulaList->setResizeMode(QListView::Adjust);
            _formulaList->setDragDropMode(QListWidget::NoDragDrop);
            _formulaList->setSelectionMode(QListWidget::SingleSelection);
            _formulaList->setMovement(QListView::Static);
            _formulaList->setViewMode(QListWidget::ListMode);
            _formulaList->setSpacing(5);
            _formulaList->setContextMenuPolicy(Qt::CustomContextMenu);
            _formulaList->setFrameShape(QFrame::NoFrame);

            auto buttonsWidget = new QWidget();
            QHBoxLayout* formulaButtonLayout = new QHBoxLayout(buttonsWidget);
            formulaButtonLayout->setContentsMargins(0, 0, 0, 0);
            formulaButtonLayout->setSpacing(2);
                    
            _appendButton = new QPushButton(q);
            _appendButton->setObjectName("_appendButton");
            _appendButton->setText(ProductDlg::tr("添加"));
            _appendButton->setFont(font);
            _modifyButton = new QPushButton(q);
            _modifyButton->setObjectName("_modifyButton");
            _modifyButton->setText(ProductDlg::tr("修改"));
            _modifyButton->setFont(font);
            _deleteButton = new QPushButton(q);
            _deleteButton->setText(ProductDlg::tr("删除"));
            _deleteButton->setObjectName("_deleteButton");
            _deleteButton->setFont(font);
            _completeButton = new QPushButton(q);
            _completeButton->setText(ProductDlg::tr("保存"));
            _completeButton->setObjectName("_completeButton");
            _completeButton->setFont(font);
            _cancelButton = new QPushButton(q);
            _cancelButton->setText(ProductDlg::tr("取消"));
            _cancelButton->setObjectName("_cancelButton");
            _cancelButton->setFont(font);
            formulaButtonLayout->addWidget(_appendButton);
            formulaButtonLayout->addWidget(_modifyButton);
            formulaButtonLayout->addWidget(_deleteButton);
            formulaButtonLayout->addWidget(_completeButton);
            formulaButtonLayout->addWidget(_cancelButton);

            formulaListLayout->addLayout(searchNameLayout);
            formulaListLayout->addWidget(_formulaList, 1);
            formulaListLayout->addWidget(buttonsWidget);

            _productViewer = new ProductWidget(type, q);

            formulaLayout->addWidget(_productViewer, 1);
            formulaLayout->addWidget(listWidget);

            _completeButton->hide();
            _cancelButton->hide();

            bool admin0 = (UserManage::instance()->permission() & PT_AddDelFormular);
            bool admin1 = (UserManage::instance()->permission() & PT_ModifyFormular);
            _appendButton->setEnabled(admin0);
            _modifyButton->setEnabled(admin1);
            _deleteButton->setEnabled(admin0);

            _operator = 0;

            update();

            QMetaObject::connectSlotsByName(q);
        }

        void ProductDlgImpl::update()
        {
            _items.clear();

            _formulaList->blockSignals(true);
            _formulaList->clear();
            _formulaList->blockSignals(false);

            QDir dir(PLScanner::instance()->productDir);

            for (auto info : dir.entryInfoList(QStringList() << "*.plsp", QDir::Files))
            {
                addItem(info.fileName().remove(".plsp"));
            }
            
            setCurrent(_currentProduct);
        }

        void ProductDlgImpl::addItem(QString name)
        {
            _formulaList->blockSignals(true);

            QListWidgetItem* item = new QListWidgetItem(_formulaList);
            item->setFlags(Qt::ItemIsTristate | Qt::ItemIsEnabled | Qt::ItemIsSelectable);
            item->setData(Qt::UserRole + 1, name);
            item->setSizeHint(QSize(250, 50));
            ListItemLabel* label = new ListItemLabel();
            label->setDispText(name);
            _formulaList->setItemWidget(item, label);

            _formulaList->blockSignals(false);

            _items[name] = item;
        }

        void ProductDlgImpl::setCurrent(QString name)
        {
            _formulaList->blockSignals(true);

            _currentProduct = name;

            if (name.isEmpty() ||
                !_items.contains(name))
            {
                _formulaList->setCurrentRow(-1);
                ProductParams params;
                _productViewer->setParams(name, params);
            }
            else
            {
                _formulaList->setCurrentItem(_items[name]);
                ProductParams params;
                if (ProductParams::loadFromLocal(params, name))
                {
                    _productViewer->setParams(name, params);
                }
                else
                {
                    OiAlerter() << ProductDlg::tr("参数加载失败!");
                }
            }

            _formulaList->blockSignals(false);

        }

        ProductDlg::ProductDlg(ProductMeasurePage type, QWidget* parent/* = NULL*/)
            : Ctrl::Dialog(parent)
        {
            OI_I(ProductDlg)->init(type);
        }

        void ProductDlg::updatePage()
        {
            OI_IMPL()->update();
        }

        void ProductDlg::setCurrent(QString name)
        {
            OI_IMPL()->setCurrent(name);
        }

        void ProductDlg::closeEvent(QCloseEvent *e)
        {
            OI_F(ProductDlg);
        }

        void ProductDlg::on__searchName_textChanged(const QString &name)
        {
            OI_F(ProductDlg);

            auto rows = d->_formulaList->count();

            for(auto i = 0; i < rows; i++)
            {
                auto item = d->_formulaList->item(i);
                auto label = reinterpret_cast<ListItemLabel*>( d->_formulaList->itemWidget(item) );
                if(label->containsText(name))
                {
                    item->setHidden(false);
                    label->setSelectText(name);
                }
                else
                {
                    item->setHidden(true);
                }
            }
        }

        void ProductDlg::on__clearSearch_clicked()
        {
            OI_F(ProductDlg);

            d->_searchName->setText(QString(""));
        }

        void ProductDlg::on__formulaList_currentRowChanged(int row)
        {
            OI_F(ProductDlg);

            if (row >= 0)
            {
                d->setCurrent(d->_formulaList->item(row)->data(Qt::UserRole + 1).toString());
            }
            else
            {
                d->setCurrent("");
            }
        }

        void ProductDlg::on__formulaList_itemDoubleClicked(QListWidgetItem* item)
        {
            OI_F(ProductDlg);

            auto newName = item->data(Qt::UserRole + 1).toString();

            if (newName == ProductParams::current())
            {
                OiAlerter() << tr("与当前配方一致，无法切换");
                return;
            }
         
            if (QMessageBox::Yes == QMessageBox::information(this, tr("提示"), tr("是否切换至配方%1？").arg(newName), QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes))
            {
                ProductParams::setNext(newName);
                close();
            }
        }

        void ProductDlg::on__appendButton_clicked()
        {
            OI_F(ProductDlg);

            GuideProductDlg guidDlg;
            d->_productViewer->setEditable(true);
            if (guidDlg.exec() == QDialog::Accepted)
            {
                d->_productViewer->setParams(guidDlg.formalName(), guidDlg.params());
                QList<QPointF> points = guidDlg.getMeasurePoints();
                for (int i = 0; i < points.size(); i++)
                {
                    d->_productViewer->addToolProfilesViewPoint(points[i]);
                    d->_productViewer->onAddTool(points[i]);
                }
                               
                d->_productViewer->updateParams();
            }
            else
            {
                return;
            }
           
            d->_operator = 1;
            d->_formulaList->setEnabled(false);
            d->_appendButton->hide();
            d->_modifyButton->hide();
            d->_deleteButton->hide();
            d->_completeButton->show();
            d->_cancelButton->show();
         
        }

        void ProductDlg::on__modifyButton_clicked()
        {
            OI_F(ProductDlg);

            if (d->_formulaList->currentRow() < 0)
            {
                return;
            }

            d->_operator = 2;

            d->_formulaList->setEnabled(false);
            d->_appendButton->hide();
            d->_modifyButton->hide();
            d->_deleteButton->hide();
            d->_completeButton->show();
            d->_cancelButton->show();

            d->_productViewer->setEditable(true);
        }

        void ProductDlg::on__deleteButton_clicked()
        {
            OI_F(ProductDlg);

            if (!d->_currentProduct.isEmpty())
            {
                if (QMessageBox::Yes == QMessageBox::information(this, tr("提示"), tr("确定删除配方？"), QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes))
                {
                    auto file = PLScanner::instance()->productDir + "/" + d->_currentProduct + ".plsp";
                    if (QFileInfo(file).exists())
                    {
                        QFile::remove(file);
                    }

                    d->_currentProduct.clear();

                    d->update();
                }
            }
        }

        void ProductDlg::on__completeButton_clicked()
        {
            OI_F(ProductDlg);

            if (d->_operator == 1)
            {
                if (!ProductParams::saveToLocal(d->_productViewer->parmas()))
                {
                    OiAlerter() << tr("新建产品失败！");
                }
                else
                {
                    d->_currentProduct = d->_productViewer->name();
                }
            }
            else if (d->_operator == 2)
            {
                if (d->_currentProduct == d->_productViewer->name())
                {
                    auto file = PLScanner::instance()->productDir + "/" + d->_currentProduct + ".plsp";
                    if(QFileInfo(file).exists())
                    {
                        QFile::remove(file);
                    }
                }

                if(!ProductParams::saveToLocal(d->_productViewer->parmas()))
                {
                    OiAlerter() << tr("修改产品失败！");
                }
                else if(d->_currentProduct != d->_productViewer->name())
                {
                    auto file = PLScanner::instance()->productDir + "/"+ d->_currentProduct + ".plsp";
                    if(QFileInfo(file).exists())
                    {
                        QFile::remove(file);
                    }

                    d->_currentProduct = d->_productViewer->name();
                }
            }

            d->_formulaList->setEnabled(true);
            d->_appendButton->show();
            d->_modifyButton->show();
            d->_deleteButton->show();
            d->_completeButton->hide();
            d->_cancelButton->hide();

            d->_productViewer->setEditable(false);
            QDir tempDir;
            QString tempFilePath = tempDir.currentPath()+"\\settings\\" + "formual.ini";  // currentPath()方法返回应用程序所在的当前目录；

            QSettings settings(tempFilePath, QSettings::Format::IniFormat);
            settings.setValue(d->_currentProduct + "/ThicknessValue", d->_productViewer->getThicknessValue());
//            Core::OiSettings()->object()->setValue(d->_currentProduct+"/ThicknessValue", d->_productViewer->getThicknessValue());
            d->update();
        }

        void ProductDlg::on__cancelButton_clicked()
        {
            OI_F(ProductDlg);

            d->_formulaList->setEnabled(true);
            d->_appendButton->show();
            d->_modifyButton->show();
            d->_deleteButton->show();
            d->_completeButton->hide();
            d->_cancelButton->hide();

            d->_productViewer->setEditable(false);

            d->update();
        }

    }
}